/**
 ******************************************************************************
 * @file           : bsp_memory_config.h
 * @brief          : BSP Memory Management Configuration Template
 ******************************************************************************
 * @attention
 *
 * BSP内存管理配置模板
 * 提供内存分配、内存池等功能配置
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_MEMORY_CONFIG_H
#define __BSP_MEMORY_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stddef.h>

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

/*============================================================================*/
/*                           内存管理类型选择                                  */
/*============================================================================*/

/**
 * @brief 内存管理类型
 * 0 = 使用标准库malloc/free
 * 1 = 使用FreeRTOS内存管理
 * 2 = 使用自定义内存池
 */
#define BSP_MEMORY_TYPE         0

/*============================================================================*/
/*                           内存池配置                                        */
/*============================================================================*/

/**
 * @brief 内存池使能
 */
#define BSP_MEMORY_POOL_ENABLE  0

/**
 * @brief 内存池大小（字节）
 */
#define BSP_MEMORY_POOL_SIZE    (32 * 1024)     /* 32KB */

/**
 * @brief 内存池块大小
 */
#define BSP_MEMORY_BLOCK_SIZE   64              /* 64字节 */

/**
 * @brief 内存池块数量
 */
#define BSP_MEMORY_BLOCK_NUM    (BSP_MEMORY_POOL_SIZE / BSP_MEMORY_BLOCK_SIZE)

/*============================================================================*/
/*                           内存对齐配置                                      */
/*============================================================================*/

/**
 * @brief 内存对齐字节数
 */
#define BSP_MEMORY_ALIGN        4               /* 4字节对齐 */

/**
 * @brief 内存对齐宏
 */
#define BSP_MEM_ALIGN(size)     (((size) + BSP_MEMORY_ALIGN - 1) & ~(BSP_MEMORY_ALIGN - 1))

/*============================================================================*/
/*                           内存统计配置                                      */
/*============================================================================*/

/**
 * @brief 内存使用统计
 */
#define BSP_MEMORY_STATS_ENABLE 1

/**
 * @brief 内存泄漏检测
 */
#define BSP_MEMORY_LEAK_CHECK   0

/*============================================================================*/
/*                           安全检查配置                                      */
/*============================================================================*/

/**
 * @brief 内存越界检查
 */
#define BSP_MEMORY_OVERFLOW_CHECK   1

/**
 * @brief 双重释放检查
 */
#define BSP_MEMORY_DOUBLE_FREE_CHECK    1

/* Exported macro ------------------------------------------------------------*/

/*============================================================================*/
/*                           内存分配宏定义                                    */
/*============================================================================*/

#if (BSP_MEMORY_TYPE == 0)
    /* 标准库malloc/free */
    #include <stdlib.h>
    
    #define BSP_MALLOC(size)        malloc(size)
    #define BSP_FREE(ptr)           free(ptr)
    #define BSP_CALLOC(num, size)   calloc(num, size)
    #define BSP_REALLOC(ptr, size)  realloc(ptr, size)

#elif (BSP_MEMORY_TYPE == 1)
    /* FreeRTOS内存管理 */
    #include "FreeRTOS.h"
    
    #define BSP_MALLOC(size)        pvPortMalloc(size)
    #define BSP_FREE(ptr)           vPortFree(ptr)
    #define BSP_CALLOC(num, size)   bsp_calloc(num, size)
    #define BSP_REALLOC(ptr, size)  bsp_realloc(ptr, size)

#elif (BSP_MEMORY_TYPE == 2)
    /* 自定义内存池 */
    #define BSP_MALLOC(size)        mem_pool_alloc(size)
    #define BSP_FREE(ptr)           mem_pool_free(ptr)
    #define BSP_CALLOC(num, size)   mem_pool_calloc(num, size)
    #define BSP_REALLOC(ptr, size)  mem_pool_realloc(ptr, size)
#endif

/*============================================================================*/
/*                           内存操作宏                                        */
/*============================================================================*/

/**
 * @brief 内存清零
 */
#define BSP_MEMSET(ptr, value, size)    memset(ptr, value, size)

/**
 * @brief 内存复制
 */
#define BSP_MEMCPY(dst, src, size)      memcpy(dst, src, size)

/**
 * @brief 内存比较
 */
#define BSP_MEMCMP(ptr1, ptr2, size)    memcmp(ptr1, ptr2, size)

/*============================================================================*/
/*                           安全分配宏                                        */
/*============================================================================*/

/**
 * @brief 安全分配内存（带检查）
 */
#define BSP_MALLOC_SAFE(ptr, size)              \
    do {                                        \
        ptr = BSP_MALLOC(size);                 \
        if (ptr == NULL) {                      \
            log_e("Memory allocation failed!"); \
        }                                       \
    } while(0)

/**
 * @brief 安全释放内存（带检查）
 */
#define BSP_FREE_SAFE(ptr)          \
    do {                            \
        if (ptr != NULL) {          \
            BSP_FREE(ptr);          \
            ptr = NULL;             \
        }                           \
    } while(0)

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/*============================================================================*/
/*                           内存池函数声明                                    */
/*============================================================================*/

#if (BSP_MEMORY_POOL_ENABLE == 1)

/**
 * @brief       初始化内存池
 */
void mem_pool_init(void);

/**
 * @brief       从内存池分配内存
 */
void* mem_pool_alloc(size_t size);

/**
 * @brief       释放内存到内存池
 */
void mem_pool_free(void *ptr);

/**
 * @brief       获取内存池使用情况
 */
void mem_pool_get_info(uint32_t *total, uint32_t *used, uint32_t *free);

#endif

/*============================================================================*/
/*                           内存统计函数                                      */
/*============================================================================*/

#if (BSP_MEMORY_STATS_ENABLE == 1)

/**
 * @brief       获取内存使用统计
 */
void mem_get_stats(uint32_t *total_alloc, uint32_t *total_free, uint32_t *peak_usage);

/**
 * @brief       打印内存使用情况
 */
void mem_print_stats(void);

/**
 * @brief       重置内存统计
 */
void mem_reset_stats(void);

#endif

#ifdef __cplusplus
}
#endif

#endif /* __BSP_MEMORY_CONFIG_H */
